package tasks

import (
	"fmt"
	"github.com/robfig/cron/v3"
	"mvip-route/service/damRed/impl"
	"net"
)

// PingTask 用于管理定时任务
type PingTask struct {
	domain string
	cron   *cron.Cron
}

// NewPingTask 创建一个新的 PingTask 实例
func NewPingTask(domain string) *PingTask {
	return &PingTask{
		domain: domain,
		cron:   cron.New(),
	}
}

// Start 启动定时任务
func (pt *PingTask) Start() {
	_, err := pt.cron.AddFunc("@every 15s", pt.executePing)
	if err != nil {
		fmt.Printf("Failed to add job: %v\n", err)
		return
	}
	pt.cron.Start()
}

// Stop 停止定时任务
func (pt *PingTask) Stop() {
	pt.cron.Stop()
}

// executePing 执行 ping 操作并检测域名是否被劫持
func (pt *PingTask) executePing() {
	service := impl.DamDomainIpService{}

	domainIPMap, err := service.GetActiveDomainMap()
	if err != nil {
		logError(fmt.Sprintf("获取域名配置失败: %v", err))
		return
	}
	for domain, expectedIP := range domainIPMap {
		ips, err := net.LookupIP(domain)
		if err != nil {
			logError(fmt.Sprintf("DNS查询失败[%s]: %v", domain, err))
			continue
		}

		if len(ips) == 0 {
			logError(fmt.Sprintf("无有效IP[%s]", domain))
			continue
		}
		pt.checkDomainIP(domain, ips[0], expectedIP)
	}
}

func (pt *PingTask) checkDomainIP(domain string, actualIP net.IP, expectedIP string) {
	if actualIP.String() != expectedIP {
		logError(fmt.Sprintf("域名被劫持：域名 %s 的实际 IP 地址为 %s，但配置的正确 IP 应为 %s", domain, actualIP, expectedIP))
		pt.handleDomainHijacking(domain, actualIP)
	} else {
		logInfo(fmt.Sprintf("域名未被劫持：域名 %s 的 IP 地址为 %s", domain, actualIP))
	}
}

func (pt *PingTask) handleDomainHijacking(domain string, ip net.IP) {
	service := impl.DamDomainIpService{}
	originalID, err := service.GetOriginalRecordID(domain)
	if err != nil {
		logError(fmt.Sprintf("获取原记录失败[%s]: %v", domain, err))
		return
	}
	result, err := service.UpdateDamDomain(originalID)
	if err != nil {
		logError(fmt.Sprintf("状态更新失败[ID:%d]: %v", originalID, err))
		return
	}
	logInfo(fmt.Sprintf("成功更新记录[ID:%d]: %s", originalID, result))
}

func logInfo(message string) {
	fmt.Println("INFO:", message)
}

func logError(message string) {
	fmt.Println("ERROR:", message)
}
